package model;

import java.util.HashMap;

import android.util.Log;
import android.view.SurfaceHolder;

import com.google.zxing.Result;

import view.Scanner;
import model.ThreadHandler.OnThreadResponseCallback;
import model.camera.CameraManager;

public class KapstokKlasse implements OnThreadResponseCallback
{
	public static final String TAG = KapstokKlasse.class.getSimpleName();
	
	//A list of holders accessible by their ID
	private HashMap<String, Holder> _holders;
	
	private ThreadHandler _handler;
	
	private CameraManager _cameraManager;
	
	private HolderFactory _holderFactory;
	
	//The Activity that handles the observers
	private Scanner _observer;

	public KapstokKlasse()
	{
		_holders = new HashMap<String, Holder>();
		_handler = new ThreadHandler(this); 
		_holderFactory = new HolderFactory();
		//_cameraManager = new CameraManager(_handler);
	}
	
	public void setObserver(Scanner observer) 
	{
		_observer = observer;
	}
	
	public void startCamera(SurfaceHolder holder)
	{
		Log.d(TAG, String.format("startPreview()"));
		if(_cameraManager == null)
			_cameraManager = new CameraManager(_handler);
		
		_cameraManager.startPreview(holder);
	}
	
	public void resumeCamera() 
	{
		if(_cameraManager != null)
			_cameraManager.release();
		_cameraManager = new CameraManager(_handler);
		
		//Assign an observer to each holder
		for (Holder holder : _holders.values()) 
		{
			_observer.addNewHolderView(holder);			//Create new view for holder
			holder.startMachineUpdateCycle(_handler); 	//Start updating machine of holder
		}
	}
	
	public void stopCamera()
	{
		if(_cameraManager != null)
			_cameraManager.release();
		_cameraManager = null;
		
		//Stop connection to webservice
		for (Holder holder : _holders.values()) 
			holder.stopThread();
		
		_holders.clear();
	}
	
	//create holders from received QR codes
	private void createHolders(Result[] results)
	{
		if(_holderFactory != null)
			_holders = _holderFactory.updateHolders(_holders, results, _observer, _handler);
	}
	
	
	// Calls received from handler
	//decoder
	@Override
	public void onDecoded(Result[] results) 
	{
		Log.d(TAG, "OnDecoded");
		createHolders(results);
	}

	@Override
	public void onDecodeFailed(String data) 
	{
		Log.d(TAG, data);
	}
	
	//serviceConnection
	@Override
	public void onNewMachineReceivedFromConnection(Machine machine) 
	{
		Log.d(TAG,String.format("new Machine received: %s", machine.getID()));
		Holder holder = _holders.get(machine.getID());
		if(holder != null)
			holder.setMachine(machine);
	}

	@Override
	public void onUpdatedInfoFromMachine(Machine machine) 
	{
		Holder holder = _holders.get(machine.getID());
		if(holder != null)
			holder.updateMachine(machine);
	}

	private void notifyError(String id, String msg)
	{
		if(_holders == null || _holders.isEmpty() || _holders.get(id) == null)
			return;
		
		_holders.get(id).notifyErrorToObservers(msg);
	}
	
	@Override
	public void onConnectionFailed(String id) 
	{	
		notifyError(id, String.format("Unable to connect to server"));
		Log.d(TAG, String.format("Connection failed: %s", id));
	}
	
	@Override
	public void onTranslationFailed(String id) 
	{
		notifyError(id, String.format("Invalid Data"));
		Log.d(TAG, String.format("Translation failed: %s", id));
	}

	@Override
	public void onNonExistantMachine(String id) 
	{
		notifyError(id, String.format("Machine not found"));
		Log.d(TAG, String.format("Machine not found: %s", id));
	}	
}
